# Windows Textmode Console Functions
# F. Mersmann, 23.03.1988, Version 4.20.20040919

""" 'normal' screen having 25 rows and 80 columns

    (0,0)                             (79,0)    (X,0,24)
      +----------------------------------+         -
      |                                  |         | V-Line for 'normal' screen
      |                                  |         |
      |                                  |         |
      |                                  |         |
      |                                  |         |
      |                                  |         |
      |                                  |         |
      |                                  |         |
      +----------------------------------+         -
    (0,24)                            (79,24)

      H-Line for 'normal' screen
      |----------------------------------| (0,Y,79)
"""

import WConio                                   # will do most of the work

BLACK = 0
BLUE = 1
GREEN = 2
CYAN = 3
RED = 4
MAGENTA = 5
BROWN = 6
LIGHTGRAY = LIGHTGREY = 7
DARKGRAY = DARKGREY = 8
LIGHTBLUE = 9
LIGHTGREEN = 10
LIGHTCYAN = 11
LIGHTRED = 12
LIGHTMAGENTA = 13
YELLOW = 14
WHITE = 15

class Console:
    """ Windows Textmode Console Functions """
    def __init__(self):
        WConio.textmode()

    def Box(self, x1, y1, x2, y2):
        """ draw simple box from (nX1,nY1) to (nX2,nY2) with a single line """
        WConio.gotoxy(x1, y1)
        WConio.putch(chr(218))
        for i in range(x1 + 1, x2):
             WConio.putch(chr(196))
        WConio.putch(chr(191))
        for i in range(y1 + 1, y2):
            WConio.gotoxy(x1, i)
            WConio.putch(chr(179))
            WConio.gotoxy(x2, i);
            WConio.putch(chr(179))
        WConio.gotoxy(x1, y2);
        WConio.putch(chr(192))
        for i in range(x1 + 1, x2):
            WConio.putch(chr(196))
        WConio.putch(chr(217))
        WConio.gotoxy(x1 + 1, y1 + 1)

    def cGets(self, length):
        """ gets (and echos) a string up to length characters long.
        VERY MINIMAL editing is allowed (basically backspace). """
        return WConio.cgets(length)

    def clrBox(self, x1, y1, x2, y2):
        """ Clear Box (writing ' '), leave border, position cursor to (x1+1, y1+1) """
        x = x1 + 1
        y = y1 + 1
        for i in range(y, y2):
            WConio.gotoxy(x, i)
            for j in range(x, x2):
                WConio.putch(' ')
        WConio.gotoxy(x1 + 1, y1 + 1)

    def clrEoln(self):
        """clears from the cursor position to the end of the line. """
        WConio.clreol()

    def clrScr(self):
        """ clears the screen and homes the cursor. """
        WConio.clrscr()

    def cPuts(self, s):
        """ prints a string starting at the current cursor position.
        Some control characters are handled, but unlike the traditional
        version '\n' doesn't drop a line in the same column, instead it
        acts like '\r\n'. """
        WConio.cputs(s)

    def delLine(self):
        """ remove a line at the current cursor position, scrolling the lower
        part of the frame up. """
        WConio.delline()

    def getCh(self):
        """ retrieves a keystroke from the console, returning a tuple of (number, string)
        containing the numeric and character values for the key hit. getch() does not echo,
        and delays until a key is available. If the key hit has no character representation
        a null string ('') is returned. Note that special keys will arrive in two steps,
        either a null byte followed by a scancode or 0340 followed by a scan code for gray keys. """
        return WConio.getch()

    def getChEcho(self):
        """ works exactly like getch(), but if the key read is printable it is echoed. """
        return WConio.getche()

    def getKey(self):
        """ returns a single string value, with special names for non-ascii keys.
         Valid keynames are listed in WConio.py, so I won't repeat them here. """
        return WConio.getkey()

    def getText(self, x1, y1, x2, y2):
        """ copies characters and attributes from the screen coordinates given and
        returns them in a string buffer. Usually used with puttext(). """
        return WConio.gettext(x1, y1, x2, y2)

    def getTextInfo(self):
        """ returns a tuple of display information. It mirrors the info returned by the
        traditional version:
        - left, top, right, bottom: window coordinates
        - textattr, normattr: current attributes
        - videomode: current video mode
        - height, width: screen size
        - curx, cury: current cursor position

        Some information is faked."""
        WConio.gettextinfo()

    def gotoXY(self, x = 0, y = 0):
        """ positions the cursor at the given coordinates. """
        WConio.gotoxy(x, y)

    def highVideo(self):
        """ activates bold (bright) video mode. """
        WConio.highvideo()

    def hLine(self, x1 = 0, y = 23, x2 = 79):          # horizontal line
        """ draw simple V-Line from (x1,y) to (x2,y) with a single line (made for Box) """
        assert(x1 >= 0)
        assert(x2 <= 79)
        WConio.gotoxy(x1, y)
        WConio.putch(chr(195))

        for i in range(x1 + 1, x2):
            WConio.gotoxy(i, y)
            WConio.putch(chr(196))

        WConio.putch(chr(180))

    def insertBlankLine(self):
        """ inserts a blank line at the current position, scrolling down the rest of the screen. """
        WConio.insline(x, y)

    def kbHit(self):
        """ WConio.kbhit() returns True if a keystroke is in the buffer, False otherwise.
        If it returns true, getch()/getkey() won't block. """
        return WConio.kbhit()

    def lowVideo(self):
        """ activates low intensity (dim) video mode. """
        WConio.lowvideo()

    def moveText(self, x1, y1, x2, y2, newx, newy):
        """ moves the given text region to the new x, y position. """
        WConio.movetext(x1, y1, x2, y2, newx, newy)

    def normVideo(self):
        """ activates normal intensity video mode. Fundamentally equal to lowvideo(). """
        WConio.normvideo()

    def putCh(self, ch):
        """ expects either a numeric or single-character string and prints it at the current position. """
        WConio.putch(ch)

    def putText(self, x1, y1, x2, y2, txt):
        """ puts the given saved text block on the screen at the given coordinates.
        The left, top, right, bottom coordinates should *probably* match the geometry
        of the similar coordinates used in the gettext() call. """
        WConio.puttext(x1, y1, x2, y2, txt)

    def setCursorType(self, mode = 1):
        """ changes the appearance of the text-mode cursor. The values for n are 0 for no cursor,
        1 for normal cursor, 2 for block cursor. """
        WConio.setcursortype(mode)

    def setTitle(self, titlestr):
        """ sets the console title to the given string """
        WConio.settitle(titlestr)

    def setX(self, x, y):
        WConio.gotoxy(x, y)
        WConio.putch(chr(197))

    def setTextAttribute(self, attr):
        """ changes the text attribute (color) for new text. The data value is formatted
        with the foreground color in the lower nibble, and the background color in the upper.
        This differs from the traditional version in that blinking is not available,
        but high-intensity backgrounds are available. See above for the color constants. """
        WConio.textattr(attr)

    def setTextBackground(self, color):
        """ sets the background color without changing the foreground. See above for the
        color constants. """
        WConio.textbackground(color)

    def setTextColor(self, color):
        """ sets the foreground color without changing the background. See above for the
        color constants. """
        WConio.textcolor(color)

    def setTextMode(self):
        """ resets default video mode, clears the screen, homes the cursor, and puts
        the cursor shape back to normal. """
        WConio.textmode()

    def ungetCh(self):
        """ pushes a keystroke back into the keyboard buffer. ch may be either an
        integer value or one-character string. Only one byte can be pushed back this way;
        that means that special keys can't be pushed, since they involve a two-byte sequence. """
        return WConio.ungetch()

    def vLine(self, x = 1, y1 = 0, y2 = 24):            # vertikal line
        """ draw simple H-Line from (x,y1) to (x,y2) with a single line (made for Box) """
        assert(y1 >= 0)
        assert(y2 <= 79)
        WConio.gotoxy(x, y1)
        WConio.putch(chr(194))
        for i in range(y1 + 1, y2):
            WConio.gotoxy(x, i)
            WConio.putch(chr(179))
        WConio.gotoxy(x, y2)
        WConio.putch(chr(193))

    def whereX(self):
        """ returns the current cursor x position. """
        WConio.wherex()

    def whereY(self):
        """ returns the current cursor y position. """
        WConio.wherey()
